using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.BizTalk.TransportProxy.Interop;
using Microsoft.BizTalk.Message.Interop;

namespace Microsoft.Samples.BizTalk.Adapter.Tcp.Receive
{
    /// <summary>
    ///     This class implements a transmitter that is called by BizTalk when returning responses.
    /// </summary>
    /// <author>
    ///     Paul Brown
    /// </author>
    public partial class Transmitter : IBTTransmitter
    {
        #region IBTTransmitter Members

        /// <summary>
        ///     This method is not implemented.
        /// </summary>
        public void Initialize(IBTTransportProxy transportProxy) {}

        /// <summary>
        ///     This method shuts down the transmitter handler.
        /// </summary>
        public void Terminate()
        {
            // Signal a waiting caller if there is one
            this._waitEvent.Set();

            // Remove ourself from array
            Transmitter.RemoveHandler(this);
        }

        /// <summary>
        ///     This method is called when the messaging engine is delivering a response back to the client.
        /// </summary>
        public bool TransmitMessage(IBaseMessage msg)
        {
            if (this.Adapter.TraceSwitch.TraceVerbose)
                TraceHelper.WriteEntry(TraceLevel.Verbose, ResourceConstants.ReceiveBizTalkHasReturnedResponse, this.ReceiveLocation.Uri, msg.MessageID);

            // Is it a NACK because we timed out?
            object ackType = msg.Context.Read(ReceiveLocation.AckType.Name.Name, ReceiveLocation.AckType.Name.Namespace);

            if (ackType != null && ackType.ToString() == "NACK")
            {
                if (this.Adapter.TraceSwitch.TraceVerbose)
                    TraceHelper.WriteEntry(TraceLevel.Verbose, ResourceConstants.ReceiveBizTalkResponseIsNack);

                // Just close client connection
                if (this.ClientSocket != null)
                {
                    this.ClientSocket.Close();
                }
            }
            else
            {
                if (this.Adapter.TraceSwitch.TraceVerbose)
                    TraceHelper.WriteEntry(TraceLevel.Verbose, ResourceConstants.ReceiveBizTalkResponseIsResponse);

                // Build a transmit work item
                TransmitWorkItem workItem = new TransmitWorkItem(this.ReceiveLocation, msg, this.ClientSocket);

                // Add to dispatcher
                this.Adapter.Dispatcher.AddWorkItem(workItem);
            }

            // Signal a waiting caller (if there is one) that a response has been received
            this._waitEvent.Set();

            // Remove ourself from array as we are done
            Transmitter.RemoveHandler(this);

            // Return false to indicate that the message is to be sent asynchronously
            return (false);
        }

        #endregion
    }
}
